using System;
using System.Collections;
using System.Collections.Generic;
using Me.Prettyprint.Cassandra.Connection;
using Me.Prettyprint.Cassandra.Service;
using Me.Prettyprint.Hector.Api;
using Me.Prettyprint.Hector.Api.Beans;
using Me.Prettyprint.Hector.Api.Factory;
using Me.Prettyprint.Hector.Api.Query;

namespace Me.Prettyprint.Cassandra.Model
{
	/// <summary>
	/// Base class for sub column query classes to extend. It expects the
    /// keyspace, and serializer for supercolumn, column and value.
	/// </summary>
	/// <typeparam name="K"></typeparam>
	/// <typeparam name="SN"></typeparam>
	/// <typeparam name="N"></typeparam>
	/// <typeparam name="V"></typeparam>
	public class AbstractSubColumnQuery<K, SN, N, V> : SubColumnQuery<K, SN, N, V>
	{
		public AbstractSubColumnQuery()
		{
		}
        public AbstractSubColumnQuery(Keyspace keyspace, Serializer<K> keySerializer, Serializer<SN> sNameSerializer,
            Serializer<N> nameSerializer, Serializer<V> valueSerializer)
        {
            SubSliceQuery = HFactory.CreateSubSliceQuery(keyspace, keySerializer, sNameSerializer, 
                nameSerializer, valueSerializer);
        }

        protected SubSliceQuery<K, SN, N, V> SubSliceQuery
        {
            get;
            set;
        }
        public SubColumnQuery<K, SN, N, V> SetKey(K key) 
        {
            SubSliceQuery.SetKey(key);
            return this;
        }
        public SubColumnQuery<K, SN, N, V> SetSuperColumn(SN superName)
        {
            SubSliceQuery.SetSuperColumn(superName);
            return this;
        }
        public SubColumnQuery<K, SN, N, V> SetColumn(N columnName) 
        {
            SubSliceQuery.ColumnNames.Add(columnName);
            return this;
        }
        public override string ToString() 
        {
            return "SubColumnQuery(" + SubSliceQuery + ")";
        }
        public SubColumnQuery<K, SN, N, V> SetColumnFamily(string cf)
        {
            SubSliceQuery.SetColumnFamily(cf);
            return this;
        }
        public QueryResult<HColumn<N, V>> Execute() 
        {
            if (SubSliceQuery.ColumnNames.Count == 1)
            {
                throw new SystemException("There should be exactly one column name set. Call setColumn");
            }
            QueryResult<ColumnSlice<N, V>> r = SubSliceQuery.Execute();
            ColumnSlice<N, V> slice = r.Get();
            List<HColumn<N,V>> columns = slice.GetColumns();
            HColumn<N, V> column = columns.Count == 0 ? null : columns[0];
            return new QueryResultImpl<HColumn<N,V>>( new ExecutionResult<HColumn<N,V>>(column, r.ExecutionTimeNano, r.HostUsed), this);
        }
	}
}